package com.szholly.pro.watergas_server.common.web;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.szholly.data.general.RowBase;
import com.szholly.plug.form.excel.utils.StringUtil;
import com.szholly.plug.safe.entity.user.UserEntity;
import com.szholly.pro.watergas_server.common.util.ExcelCreater;
import com.szholly.pro.watergas_server.common.util.JsonUtil;
import com.szholly.pro.watergas_server.ps.service.CommonService;
import com.szholly.pro.watergas_server.ps.service.ExcelCreate;
import com.szholly.utils.session.SessionFactory;
import com.szholly.utils.session.provider.ISessionProvider;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFCellUtil;
import org.apache.poi.ss.util.CellRangeAddress;
import org.htmlparser.util.ParserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.RectangleReadOnly;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

@Component
public class BaseController {

	protected final static Logger logger = LoggerFactory.getLogger(BaseController.class);

	@Autowired
	protected CommonService commonService;


	/**
	 * 输出JSON
	 * 
	 * @param response
	 * @param str
	 */
	public void outString(String str) {
		HttpServletResponse response = WebContext.getResponse();
		PrintWriter out = null;
		try {
			out = response.getWriter();
			out.write(str);
		} catch (IOException e) {
			logger.error(e.getMessage());
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}
	
	/**
	 * 输出JSON
	 * 
	 * @param response
	 * @param str
	 */
	public void outData(String str) {
		String outStr = "{\"data\":\""+str+"\"}";
		outString(outStr);
	}
	
	/**
	 * 向前台输出错误信息
	 * @param errorMsg
	 */
	public void outErrorString(String errorMsg){
		String outStr = "{\"data\":\"error\",\"msg\":\""+errorMsg+"\"}";
		outString(outStr);
	}
	
	/**
	 * 输出成功信息
	 * gislin
	 * 2016年6月28日
	 */
	public void outSuccessString(){
		outString("{\"data\":\"success\"}");
	}
	
	/**
	 * 导出excel，结合freemarker模板，先转成html然后通过poi输出成excel
	 * @param tempName 模板名称
	 * @param data 数据
	 * @param downloadfilename 下载的文件名
	 * @throws IOException
	 * @throws ParserException
	 */
	public void exportExcelWidthFreemarkerTemp(String tempName,String baseExcelField,HashMap<String, Object> data,String downloadfilename) throws IOException, ParserException{
		HttpServletRequest resq = WebContext.getRequest();
		HttpServletResponse res = WebContext.getResponse();
		String tempPath = resq.getServletContext().getRealPath("/") + "WEB-INF/freeMarkerTemp/";
		tempPath = tempPath.replaceAll("\\\\", "/");
		
		OutputStream out = res.getOutputStream();
		downloadfilename = toUtf8String(WebContext.getRequest(), downloadfilename);
		res.setContentType("application/x-msdownload;charset=utf-8");
		res.setHeader("Content-Disposition",
				"attachment;filename=" + new String(downloadfilename.getBytes("utf-8"), "ISO-8859-1"));
		ExcelCreater excelCreater = new ExcelCreater();
		excelCreater.exportExcel(tempPath,baseExcelField, tempName, data, out);
		out.flush();
		out.close();
		
	}
	
	public static String toUtf8String(HttpServletRequest request, String s) {
		String agent = request.getHeader("User-Agent");
		try {
			boolean isFireFox = (agent != null && agent.toLowerCase().indexOf("firefox") != -1);
			if (isFireFox) {
				s = new String(s.getBytes("UTF-8"), "ISO8859-1");
			} else {
				s = toUtf8String(s);
				if ((agent != null && agent.indexOf("MSIE") != -1)) {
					if (s.length() > 150) {
						// 根据request的locale 得出可能的编码
						s = new String(s.getBytes("UTF-8"), "ISO8859-1");
					}
				}
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return s;
	}

	public static String toUtf8String(String s) {

		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (c >= 0 && c <= 255) {
				sb.append(c);
			} else {
				byte[] b;
				try {
					b = Character.toString(c).getBytes("utf-8");
				} catch (Exception ex) {
					b = new byte[0];
				}
				for (int j = 0; j < b.length; j++) {
					int k = b[j];
					if (k < 0)
						k += 256;
					sb.append("%" + Integer.toHexString(k).toUpperCase());
				}
			}
		}
		return sb.toString();
	}

	public void outExcel(List<RowBase> rows, String downloadfilename, String tempName) throws IOException {
		HttpServletRequest resq = WebContext.getRequest();
		HttpServletResponse res = WebContext.getResponse();
		Configuration cfg = new Configuration();
		String tempPath = resq.getServletContext().getRealPath("/") + "WEB-INF/freeMarkerTemp/";
		cfg.setDirectoryForTemplateLoading(new File(tempPath));
		Template temp = cfg.getTemplate(tempName, "UTF-8");
		Map<String, List<RowBase>> root = new HashMap<>();
		root.put("list", rows);
		Writer out = res.getWriter();
		downloadfilename = toUtf8String(WebContext.getRequest(), downloadfilename);
		try {
			res.setContentType("application/x-msdownload;charset=utf-8");
			res.setHeader("Content-Disposition",
					"attachment;filename=" + new String(downloadfilename.getBytes("utf-8"), "ISO-8859-1"));
			temp.process(root, out);
		} catch (TemplateException e) {
			e.printStackTrace();
		}
		out.flush();
	}

	public void outExcel(List<RowBase> rows, List<String> headers, List<String> valueFields, String downloadfilename,
			String tempName, HashMap<String, Float> alertValues, String reporttitle, String wwtpname, String reporttime,
			List<String> lg) throws IOException {
		HttpServletRequest resq = WebContext.getRequest();
		HttpServletResponse res = WebContext.getResponse();
		Configuration cfg = new Configuration();
		String tempPath = resq.getServletContext().getRealPath("/") + "WEB-INF/freeMarkerTemp/";
		cfg.setDirectoryForTemplateLoading(new File(tempPath));
		Template temp = cfg.getTemplate(tempName, "UTF-8");
		Map<String, Object> root = new HashMap<>();
		root.put("list", rows);
		root.put("headers", headers);
		root.put("valuefields", valueFields);
		root.put("alertvalues", alertValues);
		root.put("lg", lg);
		downloadfilename = toUtf8String(WebContext.getRequest(), downloadfilename);
		if (!StringUtil.IsNullOrEmpty(reporttitle)) {
			root.put("reporttitle", reporttitle);
		}
		if (!StringUtil.IsNullOrEmpty(wwtpname)) {
			root.put("wwtpname", wwtpname);
		}
		if (!StringUtil.IsNullOrEmpty(reporttime)) {
			root.put("reporttime", reporttime);
		}
		Writer out = res.getWriter();
		try {
			res.setContentType("application/x-msdownload;charset=utf-8");
			res.setHeader("Content-Disposition",
					"attachment;filename=" + new String(downloadfilename.getBytes("utf-8"), "ISO-8859-1"));
			temp.process(root, out);
		} catch (TemplateException e) {
			e.printStackTrace();
		}
		out.flush();
	}

	public void outExcel(List<RowBase> rows, List<String> headers, List<String> valueFields, String downloadfilename,
			String tempName) throws IOException {
		outExcel(rows, headers, valueFields, downloadfilename, tempName, null, null, null, null, null);
	}

	public void outReportExcel(List<RowBase> rows, List<String> headers, List<String> valueFields,
			List<String> valueFieldsMin, List<String> valueFieldsMax, List<String> valueFieldsAvg,
			List<HashMap<String, String>> MinData, List<HashMap<String, String>> MaxData,
			List<HashMap<String, String>> AvgData, List<String> listname, List<String> listtime,
			List<String> listreport, HashMap<String, Float> uplistData, HashMap<String, Float> MINudData,
			HashMap<String, Float> MAXudData, HashMap<String, Float> AVGudData, List<String> lg,
			String downloadfilename, String tempName) throws IOException {
		HttpServletRequest resq = WebContext.getRequest();
		HttpServletResponse res = WebContext.getResponse();
		Configuration cfg = new Configuration();
		String tempPath = resq.getServletContext().getRealPath("/") + "WEB-INF/freeMarkerTemp/";
		cfg.setDirectoryForTemplateLoading(new File(tempPath));
		Template temp = cfg.getTemplate(tempName, "UTF-8");
		Map<String, Object> root = new HashMap<>();
		downloadfilename = toUtf8String(WebContext.getRequest(), downloadfilename);
		root.put("list", rows);
		root.put("listmin", MinData);
		root.put("listmax", MaxData);
		root.put("listavg", AvgData);
		root.put("headers", headers);
		root.put("valueFields", valueFields);
		root.put("valueFieldsMin", valueFieldsMin);
		root.put("valueFieldsMax", valueFieldsMax);
		root.put("valueFieldsAvg", valueFieldsAvg);
		root.put("uplistData", uplistData);
		root.put("MINudData", MINudData);
		root.put("MAXudData", MAXudData);
		root.put("AVGudData", AVGudData);
		root.put("lg", lg);

		if (listname.size() > 0) {
			root.put("listname", listname);
		}
		;
		if (listtime.size() > 0) {
			root.put("listtime", listtime);
		}
		if (listreport.size() > 0) {
			root.put("listreport", listreport);
		}

		Writer out = res.getWriter();
		try {
			res.setContentType("application/x-msdownload;charset=utf-8");
			res.setHeader("Content-Disposition",
					"attachment;filename=" + new String(downloadfilename.getBytes("utf-8"), "ISO-8859-1"));
			temp.process(root, out);
		} catch (TemplateException e) {
			e.printStackTrace();
		}
		out.flush();
	}

	protected void outExcelGeneral(Map<String, Object> data, String downloadfilename, String templateName)
			throws IOException {
		HttpServletRequest resq = WebContext.getRequest();
		HttpServletResponse res = WebContext.getResponse();
		Configuration cfg = new Configuration();
		String tempPath = resq.getServletContext().getRealPath("/") + "WEB-INF/freeMarkerTemp/";
		cfg.setDirectoryForTemplateLoading(new File(tempPath));
		Template temp = cfg.getTemplate(templateName, "UTF-8");
		Writer out = res.getWriter();
		downloadfilename = toUtf8String(WebContext.getRequest(), downloadfilename);
		try {
			res.setContentType("application/x-msdownload;charset=utf-8");
			//解决火狐也乱码问题
			res.setHeader("Content-Disposition", "attachment; filename=\"" + downloadfilename + "\"");			
			temp.process(data, out);
		} catch (TemplateException e) {
			e.printStackTrace();
		}
		out.flush();
	}
	
	protected void outPutExcellWithPicture(Map<String,String> parms,Map<String,Object> data,String template,String fileName, String stationName) throws Exception{
		String mn = parms.get("mn");
		String parmsToChar = parms.get("parmsToChar");
		String parmToChecks = parms.get("parmToChecks");
		String[] parmToChar = parmsToChar.split(",");
		String[] parmToCheck=parmToChecks.split(",");
		String path = WebContext.getServerPath();
		HttpServletResponse res = WebContext.getResponse();
		List<String> list = new ArrayList<String>();  
		String  headers = data.get("headers").toString();
		String statName = data.get("name").toString();
		String title = data.get("title").toString();
		String time = data.get("time").toString();
		Object datas = data.get("list");
		@SuppressWarnings("unchecked")
		List<RowBase> dataList =(List<RowBase>)datas;
		headers = headers.substring(1, headers.length()-1);
		String[] headArray = headers.split(",");
        ExcelCreate s = new ExcelCreate();
        s.createSheet("报表数据");  
		//表头站点名称，报表日期
        list.add(title);
        s.addRow(list,parmToCheck.length);
        list.clear();
        list.add(statName);
        list.add(time);
        s.addRow(list,parmToCheck.length);
        list.clear();
        //添加污染物参数表头
		for(int i=0;i<headArray.length;i++) {
			list.add(headArray[i]);
		}
        s.addRow(list,parmToCheck.length);
        String downloadfilename = toUtf8String(WebContext.getRequest(), fileName);
        for (int i = 0; i < dataList.size(); i++) {  
            List<Object> lists = new ArrayList<Object>();  
        	RowBase dataContent = dataList.get(i);
        	String datatime = dataContent.getSafeString("DATATIME");
        	lists.add(datatime);
        	for(int j=0;j<parmToCheck.length;j++) {
        		String parmCode = parmToCheck[j].toUpperCase();
        		String parmData = dataContent.getSafeString("P"+parmCode+"AVG");
        		lists.add(parmData);
        	}
            s.addRow(lists,parmToCheck.length);  
        }  
		try {
			for(int i=0;i<parmToChar.length;i++) {
				String parmName = parmToChar[i];
				HSSFSheet sheet1 = s.wb.createSheet(parmName+"平均值"); // 添加一个新的sheet
				
				//修改excell，增加图片
				FileOutputStream fileOut = null;
				BufferedImage bufferImg = null;
				bufferImg = ImageIO.read(new File(path+"\\reportChar\\"+mn+"-"+parmName+".png"));
		        //创建第一行
		        HSSFRow row = sheet1.createRow((int) 4); 
		      //设置单元格格式
				HSSFCellStyle cs = getCellStyle(s.wb);
		        //设置row的高度
		        row.setHeightInPoints(30);
		        HSSFCell cell = row.createCell(1);  
		        CellRangeAddress rg = new CellRangeAddress(4, 4, 1, 10); 
		        
		        sheet1.addMergedRegion(rg); 
		        setRegionStyle(sheet1,rg,cs);
		        cell.setCellValue(stationName+parmName+"均值");  
		        cell.setCellStyle(cs);  
				ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); 

				//给图形绘制边框
				int width = bufferImg.getWidth();
				int height = bufferImg.getHeight();
				Graphics graphics = bufferImg.getGraphics();  
			    graphics.setColor(Color.BLACK);     
			    graphics.drawRect(0, 0, width-1, height-1);  
			    graphics.drawRect(1, 1, width-1, height-1);  
			    graphics.drawRect(0, 0, width-2, height-2);  
				   
				ImageIO.write(bufferImg, "png", byteArrayOut);
				
				HSSFPatriarch patriarch = sheet1.createDrawingPatriarch();
				// anchor主要用于设置图片的属性
				HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 250, (short) 1, 8, (short) 10, 22);
				// 插入图片
				patriarch.createPicture(anchor, s.wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
				
				fileOut = new FileOutputStream(path+"\\reportChar\\"+"dataReport.xls");
				
				// 写入excel文件
				s.wb.write(fileOut);
				System.out.println("----Excle文件已生成------");
				if (fileOut != null) {
					fileOut.close();
				}
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		OutputStream out = res.getOutputStream();
		res.setContentType("application/x-msdownload;charset=gb2312");
		res.setHeader("Content-Disposition","attachment;filename=" + new String(downloadfilename.getBytes("utf-8"), "ISO-8859-1"));
		// 写入excel文件
		s.wb.write(out);
		out.flush();
	}
	/**
	 * 合并单元格以后，对单元格加边框
	 * @param sheet
	 * @param region
	 * @param cs
	 */
   private void setRegionStyle(HSSFSheet sheet, CellRangeAddress region , HSSFCellStyle cs) {
       for (int i = region.getFirstRow(); i <= region.getLastRow(); i ++) {
           HSSFRow row = HSSFCellUtil.getRow(i, sheet);
           for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
               HSSFCell cell = HSSFCellUtil.getCell(row, (short)j);
               cell.setCellStyle(cs);
           }
       }
   }

	/**
	 * 导出Word
	 * 
	 * @param root
	 * @param templateFile
	 * @param downloadfilename
	 * @throws IOException
	 */
	protected void outWord(Map<String, Object> root, String templateFile, String downloadfilename) throws IOException {
		HttpServletRequest resq = WebContext.getRequest();
		HttpServletResponse res = WebContext.getResponse();
		Configuration config = new Configuration();
		String tempPath = resq.getServletContext().getRealPath("/") + "WEB-INF/freeMarkerTemp/";
		config.setDirectoryForTemplateLoading(new File(tempPath));
		config.setDefaultEncoding("UTF-8");
		Template t = config.getTemplate(templateFile, "UTF-8");
		downloadfilename = toUtf8String(WebContext.getRequest(), downloadfilename);
		Writer out = res.getWriter();
		try {
			res.setContentType("application/x-msdownload;charset=utf-8");
			res.setHeader("Content-Disposition",
					"attachment;filename=" + new String(downloadfilename.getBytes("utf-8"), "ISO-8859-1"));
			t.process(root, out);
		} catch (TemplateException e) {
			e.printStackTrace();
		}
		out.flush();
	}
		/**
		 * PDF导出
		 * @param root
		 * @param templateFile
		 * @param downloadfilename
		 * @throws IOException
		 * @throws DocumentException
		 * @throws TemplateException
		 */
		protected void outPDF(Map<String, Object> data, String templateFile, String downloadfilename,Boolean format) throws IOException, DocumentException, TemplateException {
			HttpServletRequest resq = WebContext.getRequest();
			HttpServletResponse res = WebContext.getResponse();
			String tempPath = resq.getServletContext().getRealPath("/") + "WEB-INF/freeMarkerTemp/";
			ByteArrayOutputStream htmlOut = new ByteArrayOutputStream();
			OutputStreamWriter htmlWriter = new OutputStreamWriter(htmlOut);
			
			downloadfilename = toUtf8String(WebContext.getRequest(), downloadfilename);
			
			Configuration freeMarkerconfig = new Configuration();
			freeMarkerconfig.setDirectoryForTemplateLoading(new File(tempPath));
			freeMarkerconfig.setDefaultEncoding("UTF-8");
			Template freeMarkerTemplateerconfig = freeMarkerconfig.getTemplate(templateFile, "UTF-8");
			
			freeMarkerTemplateerconfig.process(data, htmlWriter);//往模板中写入数据
			htmlWriter.flush();
			htmlOut.flush();
			
			//输出流转输入流
			ByteArrayInputStream htmlIn = new ByteArrayInputStream(htmlOut.toByteArray());
			OutputStream out = res.getOutputStream();//写入
			Document pdfDocument=null;
			if(format==true){
				pdfDocument = new Document();	
			}else{
				RectangleReadOnly rec=new RectangleReadOnly(842f,595f);
				pdfDocument = new Document(rec);	
			}
			PdfWriter pdfWriter = PdfWriter.getInstance(pdfDocument, out);
			pdfDocument.open();
			try {
				
				res.setContentType("application/x-msdownload;charset=utf-8");
				res.setHeader("Content-Disposition",
						"attachment;filename=" + new String(downloadfilename.getBytes("utf-8"), "ISO-8859-1"));
				XMLWorkerHelper.getInstance().parseXHtml(pdfWriter, pdfDocument,htmlIn);//生成PDF
				out.flush();
				pdfWriter.flush();
				pdfDocument.close();
			} catch (Exception e) {
				e.printStackTrace();
			}		
		}
		/**
		 * 使用html模板导出excel
		 * @param downloadfilename
		 */
		protected void HtmlToExcel(Map<String, Object> data, String templateFile, String downloadfilename){
			 try {  
					HttpServletRequest resq = WebContext.getRequest();
					HttpServletResponse res = WebContext.getResponse();
		        	Configuration cfg = new Configuration();
		    		String tempPath =resq.getServletContext().getRealPath("/") + "WEB-INF/freeMarkerTemp/";
		    		cfg.setDirectoryForTemplateLoading(new File(tempPath));
		    		cfg.setDefaultEncoding("UTF-8");
		    		Template template = cfg.getTemplate(templateFile, "UTF-8"); 
		    		downloadfilename = toUtf8String(WebContext.getRequest(), downloadfilename);
		            Writer out = res.getWriter(); 	
		        
		            try {
		    			res.setContentType("application/vnd.ms-excel;charset=utf-8");
		    			res.setHeader("Content-Disposition",
		    					"attachment;filename=" + new String(downloadfilename.getBytes("utf-8"), "ISO-8859-1"));
		    			 template.process(data, out); 
		    		} catch (TemplateException e) {
		    			e.printStackTrace();
		    		}
		           
		        } catch (Exception e) {  
		            e.printStackTrace();  
		        }  
		}

	/**
	 * 根据污水厂id和排口类型获取站点id
	 * 
	 * @param wwtpid
	 * @param stationType
	 * @return
	 */
	protected String getStationId(String wwtpid, String flowType) {
		RowBase row = commonService.getStation(wwtpid, flowType);
		return row == null ? null : row.getSafeString("CODE");
	}

	/**
	 * 获取当前登录用户信息
	 * @return
	 */
	protected String getCurrentUserJsonString() {
		
		ISessionProvider session = SessionFactory.getSession();
		UserEntity userEntity = session != null ? (UserEntity) session.getObject(ISessionProvider.UserEntity) : null;

		String json = JsonUtil.ConvertObjectToJson(userEntity);
		return json;
	}
	
	/**
	 * 设置workbookStyle
	 * @param workbook
	 * @return
	 */
	private HSSFCellStyle getCellStyle(HSSFWorkbook workbook){
		HSSFCellStyle cs = workbook.createCellStyle();  
        cs.setAlignment(HSSFCellStyle.ALIGN_CENTER);  
  
        cs.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框  
        cs.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框  
        cs.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框  
        cs.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框  
  
        //设置字体:  
        HSSFFont font = workbook.createFont();  
        font.setFontName("黑体");  
        font.setFontHeightInPoints((short) 20);//设置字体大小  
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//粗体显示  
        
  
        cs.setFont(font);//要用到的字体格式  
        return cs;
	}
}
